package club.jdiy.core.properties;

import java.util.Objects;
import java.util.Set;

import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;

import club.jdiy.core.base.domain.Ret;
import lombok.extern.slf4j.Slf4j;
import org.hibernate.validator.internal.engine.path.PathImpl;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.BindException;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;

/**
 * JDiy 内置 hibernate.validator自动化验证器.
 *
 * @author ziquee(子秋) QQ号:39886616 主页: http://www.jdiy.club
 * @version 20210212
 */
@Slf4j
@ControllerAdvice
public class ValidationAdvice {

    @ExceptionHandler(value = BindException.class)
    public ResponseEntity<Object> handleMethodVoArgumentNotValidException(BindException ex) {
        FieldError err = ex.getFieldError();
        String message = err != null ? "参数{".concat(err.getField()).concat("} ").concat(Objects.requireNonNull(err.getDefaultMessage())) : "参数错误";
        log.info("{} -> {}", err != null ? err.getObjectName() : null, message);
        return new ResponseEntity<>(new Ret<>(Ret.RetCode.invalid_param.getCode(), message, err != null ? err.getField() : null), HttpStatus.OK);
    }

    @ExceptionHandler(value = ConstraintViolationException.class)
    public ResponseEntity<Object> handleMethodArgumentNotValidException(ConstraintViolationException ex) {
        Set<ConstraintViolation<?>> constraintViolations = ex.getConstraintViolations();
        for (ConstraintViolation<?> constraintViolation : constraintViolations) {
            PathImpl pathImpl = (PathImpl) constraintViolation.getPropertyPath();
            String paramName = pathImpl.getLeafNode().getName();
            String message = "参数{".concat(paramName).concat("} ").concat(constraintViolation.getMessage());
            log.info("{} -> {} -> {}", constraintViolation.getRootBeanClass().getName(), pathImpl.toString(), message);
            return new ResponseEntity<>(new Ret<>(Ret.RetCode.invalid_param.getCode(), message, paramName), HttpStatus.OK);
        }
        return new ResponseEntity<>(Ret.error(ex), HttpStatus.OK);
    }

}